﻿Imports System.ComponentModel
Imports System.Drawing.Imaging

<ToolboxItem(True), ToolboxBitmap(GetType(System.Windows.Forms.PictureBox))>
Public Class PictureView
    Inherits FileManager

    Public Sub New()

        ' 此调用是设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
        SetStyle(System.Windows.Forms.ControlStyles.ContainerControl, False)
    End Sub

    ''' <summary>
    ''' 图片集合
    ''' </summary>
    ''' <returns></returns>
    <Browsable(False)>
    Public ReadOnly Property Images As PictureView.PictureItemCollection
        Get
            If _Images Is Nothing Then
                _Images = New PictureView.PictureItemCollection(Me)
            End If
            Return _Images
        End Get
    End Property
    Private _Images As PictureView.PictureItemCollection

    ''' <summary>
    ''' 获取缩略图的尺寸
    ''' </summary>
    ''' <returns></returns>
    <Browsable(False)>
    Public ReadOnly Property ThumbnailSize As Integer
        Get
            Return 80
        End Get
    End Property

    ''' <summary>
    ''' 返回缩略图的路径。
    ''' </summary>
    ''' <returns></returns>
    <Browsable(False)>
    Public ReadOnly Property ThumbnailPath As String
        Get
            Dim Path As String = My.Computer.FileSystem.CombinePath(Application.StartupPath, "Thumbnail")
            If Me.DesignMode = False AndAlso My.Computer.FileSystem.DirectoryExists(Path) = False Then
                My.Computer.FileSystem.CreateDirectory(Path)
            End If
            Return Path
        End Get
    End Property

    ''' <summary>
    ''' 返回附件的路径。
    ''' </summary>
    ''' <returns></returns>
    <Browsable(False)>
    Public ReadOnly Property AttachmentPath As String
        Get
            Dim Path As String = My.Computer.FileSystem.CombinePath(Application.StartupPath, "Attachments")
            If Me.DesignMode = False AndAlso My.Computer.FileSystem.DirectoryExists(Path) = False Then
                My.Computer.FileSystem.CreateDirectory(Path)
            End If
            Return Path
        End Get
    End Property

#Region "PictureBoxItem事件"

    Private _SelectedItem As PictureItem

    ''' <summary>
    ''' 当前选择图片
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Browsable(False), DefaultValue(CStr(Nothing))>
    Public Property SelectedItem As PictureItem
        Get
            Return Me._SelectedItem
        End Get
        Set(value As PictureItem)
            Try
                If Me.SelectedItem IsNot value Then
                    If Me.SelectedItem IsNot Nothing Then
                        Me.SelectedItem.Invalidate()
                    End If
                    Me._SelectedItem = value
                    If Me.SelectedItem IsNot Nothing Then
                        Me.SelectedItem.Invalidate()
                        If AutoZoom = True Then
                            Me.SplitContainerControl1.Panel1.AutoScrollMinSize = New Size(Me.PictureBox1.Image.Size)
                        End If

                        Me.SelectedItem.GetImage()
                        'RaiseEvent SelectedItemed(Me, SelectedItem)
                    Else
                        If AutoZoom = True Then
                            Me.SplitContainerControl1.Panel1.AutoScrollMinSize = New Size(0, 0)
                        End If
                        If Me.PictureBox1.Image IsNot Nothing Then Me.PictureBox1.Image.Dispose()
                        Me.PictureBox1.Image = Nothing
                    End If
                End If
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try

        End Set
    End Property
    <DefaultValue(False), Browsable(False)>
    Public Property AutoZoom As Boolean
        Get
            Return Me.m_AutoZoom
        End Get
        Set(value As Boolean)
            Me.m_AutoZoom = value
            If value = True AndAlso Me.PictureBox1.Image IsNot Nothing Then
                Me.SplitContainerControl1.Panel1.AutoScrollMinSize = New Size(Me.PictureBox1.Image.Size)
            Else
                Me.SplitContainerControl1.Panel1.AutoScrollMinSize = New Size(0, 0)
            End If
        End Set
    End Property
    Private m_AutoZoom As Boolean = False

#End Region
    Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
        'If Me.Upload = UploadModeEnum.local Then
        Dim dialog As New System.Windows.Forms.OpenFileDialog
        dialog.Multiselect = Me.MultiAddImage
        dialog.Filter = Me.Filter  '设置筛选器
        If dialog.ShowDialog = System.Windows.Forms.DialogResult.OK Then
            If Me.MultiImageMode = False Then
                Me.Images.Clear()
            End If
            For Each FileName As String In dialog.FileNames
                Dim Info As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(FileName)
                Dim Item As New PictureView.PictureItem
                Item.Id = System.Guid.NewGuid.ToString.Replace("-", Nothing).ToUpper & Info.Extension
                Item.LocalPath = FileName
                Item.Name = My.Computer.FileSystem.GetName(FileName)

                'Select Case Me.CacheMode
                '    Case FileEdit.CacheModeEnum.File
                '        My.Computer.FileSystem.CopyFile(FileName, Application.StartupPath & "\Attachments\" & Item.Id)
                '        Using bmp As New Bitmap(FileName)
                '            Dim img As System.Drawing.Image = GetThumbnailImage(bmp, Me.ThumbnailSize)
                '            If My.Computer.FileSystem.DirectoryExists(Application.StartupPath & "\Thumbnail") = False Then
                '                My.Computer.FileSystem.CreateDirectory(Application.StartupPath & "\Thumbnail")
                '            End If
                '            img.Save(Application.StartupPath & "\Thumbnail\" & Item.Id, ImageFormat.Png)
                '        End Using
                'End Select

                Me.Images.Add(Item)
            Next
        End If
    End Sub

    Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
        If Me.SelectedItem IsNot Nothing AndAlso System.Windows.Forms.MessageBox.Show("确定要删除当前选定的图片吗？", "提示", System.Windows.Forms.MessageBoxButtons.OKCancel, System.Windows.Forms.MessageBoxIcon.Warning) = System.Windows.Forms.DialogResult.OK Then
            Me.Images.Remove(Me.SelectedItem)
        End If
    End Sub

    Friend Function GetThumbnailImage(ByVal bmp As Bitmap, ByVal MaxSize As Integer) As System.Drawing.Image
        Dim Width_bl As Double = bmp.Width / MaxSize
        Dim Height_bl As Double = bmp.Height / MaxSize
        Dim bl As Double = Math.Max(Width_bl, Height_bl)
        Return bmp.GetThumbnailImage(bmp.Width / bl, bmp.Height / bl, Function() As Boolean
                                                                          Return False
                                                                      End Function, IntPtr.Zero)
    End Function

    <DefaultValue(CStr(Nothing))>
    <Browsable(False)>
    Public Overloads Property Value As String
        Get
            Return MyBase.Value
        End Get
        Set(value As String)
            MyBase.Value = value
            If Updating = False Then
                WindowsAPI.LockWindowUpdate(Me.Handle)
                Me.Images.Clear(True)
                For Each item As FileManagerItem In Me.Files
                    Dim image As New PictureItem
                    image.Id = item.Id
                    image.Name = item.Name
                    Me.Images.Add(image, True)
                Next
                If Me.Images.Count > 0 Then
                    Me.SelectedItem = Me.Images(0)
                End If
                WindowsAPI.LockWindowUpdate(IntPtr.Zero)
            End If
        End Set
    End Property

    ''' <summary>
    ''' 获取或设置是否开启多图模式。
    ''' </summary>
    ''' <returns></returns>
    <DefaultValue(True)>
    <Category("杂项"), Description(" 获取或设置是否开启多图模式。")>
    Public Property MultiImageMode() As Boolean
        Get
            Return Me.SplitContainerControl1.PanelVisibility = DevExpress.XtraEditors.SplitPanelVisibility.Both
        End Get
        Set(ByVal value As Boolean)
            Me.SplitContainerControl1.PanelVisibility = IIf(value, DevExpress.XtraEditors.SplitPanelVisibility.Both, DevExpress.XtraEditors.SplitPanelVisibility.Panel1)
        End Set
    End Property

    <DefaultValue(True)>
    Public Property MultiAddImage As Boolean = True

    ''' <summary>
    ''' 设置筛选器
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DefaultValue(CStr("图形文件|*.bmp;*.jpg;*.gif;*.png"))>
    Public Property Filter As String
        Get
            Return Me._Filter
        End Get
        Set(value As String)
            Me._Filter = value
        End Set
    End Property
    Private _Filter As String = "图形文件|*.bmp;*.jpg;*.gif;*.png"

    ''' <summary>
    ''' 逻辑型，是否在PictureViewer的底端显示增加、删除、清除、打开等命令。
    ''' </summary>
    ''' <returns></returns>
    <DefaultValue(True)>
    <Category("外观"), Description("逻辑型，是否在PictureViewer的底端显示增加、删除、清除、打开等命令。")>
    Public Property CommandVisible As Boolean
        Get
            Return Me.PanelControl1.Visible
        End Get
        Set(ByVal value As Boolean)
            Me.PanelControl1.Visible = value
        End Set
    End Property

    Private Sub PictureView_AddFileing(sender As Object, ByVal e As AddFileingEventArgs) Handles MyBase.AddFileing

    End Sub

    Private Sub FlowLayoutPanel1_ControlAdded(sender As Object, e As ControlEventArgs) Handles FlowLayoutPanel1.ControlRemoved, FlowLayoutPanel1.ControlAdded

    End Sub


    Public Sub LoadAsync(ByVal Value As PictureView.PictureItem, ByVal Uri As Uri)
        If Me.LoadCollection.ContainsKey(Value) = False Then
            Me.LoadCollection.Add(Value, Uri)
        End If
        If Me.LoadCollection.Count > 0 Then
            PictureBox2_LoadCompleted(PictureBox2, Nothing)
        End If
    End Sub

    Private ReadOnly Property LoadCollection As Dictionary(Of PictureView.PictureItem, Uri)
        Get
            If _LoadCollection Is Nothing Then
                _LoadCollection = New Dictionary(Of PictureView.PictureItem, Uri)
            End If
            Return _LoadCollection
        End Get
    End Property
    Private _LoadCollection As Dictionary(Of PictureView.PictureItem, Uri)

    Private Sub PictureBox2_LoadCompleted(sender As Object, e As AsyncCompletedEventArgs) Handles PictureBox2.LoadCompleted
        If e IsNot Nothing AndAlso e.Cancelled = False AndAlso e.Error Is Nothing AndAlso Me.PictureBox2.Tag IsNot Nothing Then
            Dim Item As PictureView.PictureItem = Me.PictureBox2.Tag
            Dim Image As System.Drawing.Image = Me.PictureBox2.Image
            If My.Computer.FileSystem.FileExists(Me.AttachmentPath & "\" & Item.Id) = False Then
                Image.Save(Me.AttachmentPath & "\" & Item.Id)
            End If
            If Me.SelectedItem Is Item Then
                Me.PictureBox1.Image = Image.Clone
            End If
        ElseIf e IsNot Nothing AndAlso e.Error IsNot Nothing AndAlso Me.PictureBox2.Tag Is Me.SelectedItem Then
            Me.PictureBox1.Image = Me.PictureBox1.ErrorImage.Clone
        End If

        If Me.PictureBox2.Tag IsNot Nothing Then
            Me.LoadCollection.Remove(Me.PictureBox2.Tag)
            Me.PictureBox2.Tag = Nothing
        End If
        If Me.SelectedItem IsNot Nothing AndAlso Me.LoadCollection.ContainsKey(Me.SelectedItem) Then
            Me.PictureBox2.Tag = Me.SelectedItem
            Me.PictureBox2.LoadAsync(Me.LoadCollection(Me.SelectedItem).ToString)
        Else
            'For Each item As PictureView.Image In Me.LoadCollection.Keys
            '    If Me.Images.Contains(item) Then
            '        Me.PictureBox2.Tag = item
            '        Me.PictureBox2.LoadAsync(Me.LoadCollection(item).ToString)
            '        Exit Sub
            '    End If
            'Next
        End If
    End Sub

    'Private Sub FlowLayoutPanel1_SizeChanged(sender As Object, e As EventArgs) Handles FlowLayoutPanel1.SizeChanged
    '    Dim Height As Integer = 60 + Me.FlowLayoutPanel1.Margin.Top + Me.FlowLayoutPanel1.Margin.Bottom + Me.SplitContainer1.SplitterWidth
    '    If Me.FlowLayoutPanel1.HorizontalScroll.Visible = True Then
    '        Height += 17
    '    End If
    '    Me.SplitContainerControl1.SplitterPosition = Me.SplitContainerControl1.Height - Height
    'End Sub



    Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
        If Me.DesignMode AndAlso Me.BindingField.DataSource IsNot Nothing Then
            TextRenderer.DrawText(e.Graphics, Me.BindingField.ToString, Me.Font, New Rectangle(0, 0, PictureBox1.Width, PictureBox1.Height), Me.ForeColor, Color.Transparent, TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter)
        End If
    End Sub
End Class
